//This code originally came from the Visual Studio SDK for VS2005 and has been customized.
//This code was obtained from the 2006.09 version of the SDK.
//The original version can be found under the name of: C# Example.SyncronousXMLDesigner
/***************************************************************************

Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

***************************************************************************/

using System;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using MSVSIP = Microsoft.VisualStudio.Shell;
using ErrorHandler = Microsoft.VisualStudio.ErrorHandler;
using EnvDTE80;
using EnvDTE;

//C:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Tools\Bin\RegPkg.exe /root:8.0Exp C:\<name>.dll
//if on vista the program files might be -> Program Files(x86) instead of -> Program Files.

namespace EventAbstractionAPI.RuleEditor
{
    [MSVSIP.DefaultRegistryRoot(@"Software\Microsoft\VisualStudio\8.0Exp")]
    [MSVSIP.PackageRegistration(UseManagedResourcesOnly = true)]
    [MSVSIP.ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]

    //[MSVSIP.DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\8.0")]
    //[MSVSIP.PackageRegistration(UseManagedResourcesOnly = true)]
    //     [MSVSIP.InstalledProductRegistration(false, "#100", "#102", "1.0", IconResourceID = 400)]
    //     [MSVSIP.ProvideLoadKey("Standard", "1.0", "R2ML EDITOR", "Company", 1)]
    //     [MSVSIP.ProvideMenuResource(1000, 1)]

    // This registration takes advantage of extensibility of the XML Editor to associate a 
    // special designer with an XML namespace and file extension. This registration will
    // add an entry under HKLM\Software\Microsoft\VisualStudio\<version>\XmlDesigners.
    // It is possible to associate a designer view with a file extension or an XML Namespace,
    // or require both to match. If the XML Editor encounters one of these files, then it
    // will enable the "View.View Designer" command inside of the editor as well as to 
    // set the VSHPROPID_ItemSubType property to "Designer" for the project. This will 
    // cause the VB/VC#/VJ# projects to enable the ViewCode/ViewDesigner commands inside of the
    // Solution Explorer for this file.
    // In our case we register that our editor is a Designer View for the ".addin" file
    // with the "AutomationExtensibility" XML Namespace. 

    [ProvideXmlViewAttribute(typeof(EditorFactory), "{7651a702-06e5-11d1-8ebd-00a0c90f26ea}",
              Name = "Rule Editor",
              Namespace = "http://www.ruleml.org/dtd/0.83/ruleml-oodatalog.dtd",
              Extension = "r2ml",
              MatchBoth = false)]

    // We register that our editor supports LOGVIEWID_Designer logical view
    [MSVSIP.ProvideEditorLogicalView(typeof(EditorFactory), "{7651a702-06e5-11d1-8ebd-00a0c90f26ea}")]

    // We register our AddNewItem Templates for all of the projects we want to be available for:
    // Miscellaneous Files Project

    //[MSVSIP.ProvideEditorExtension(typeof(EditorFactory), ".r2ml", 32), ProvideOpenWithEntry(
    //[MSVSIP.ProvideEditorLogicalView
    [MSVSIP.ProvideEditorExtension(typeof(EditorFactory), ".r2ml", 32,
              ProjectGuid = "{A2FE74E1-B743-11d0-AE1A-00A0C90FFFC3}",
              TemplateDir = "..\\Templates",
              NameResourceID = 107)]
    // Solution Folders Project
    [MSVSIP.ProvideEditorExtension(typeof(EditorFactory), ".r2ml", 32,
              ProjectGuid = "{2150E333-8FDC-42a3-9474-1A3956D46DE8}",
              TemplateDir = "..\\Templates",
              NameResourceID = 107)]
    // Microsoft Visual Basic Project
    //[MSVSIP.ProvideEditorExtension(typeof(EditorFactory), ".r2ml", 32,
    //         ProjectGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}",
    //          TemplateDir = "..\\Templates",
    //          NameResourceID = 107)]
    // Microsoft Visual C# Project
    [MSVSIP.ProvideEditorExtension(typeof(EditorFactory), ".r2ml", 32,
        ProjectGuid = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}",
          TemplateDir = "..\\Templates",
          NameResourceID = 107)]
    //// Microsoft Visual J# Project
    //[MSVSIP.ProvideEditorExtension(typeof(EditorFactory), ".r2ml", 32,
    //       ProjectGuid = "{E6FDF86B-F3D1-11D4-8576-0002A516ECE8}",
    //          TemplateDir = "..\\Templates",
    //          NameResourceID = 107)]

    [Guid("233FC21C-D6C7-4af3-B353-3B1E758B50F8")]
    public class RuleEditorPackage : MSVSIP.Package
    {
        private EditorFactory editorFactory;

        /// <summary>
        /// PackageSingleViewEditor contructor.
        /// While we could have used the default constructor, adding the Trace makes it
        /// possible to verify that the package was created without having to set a break
        /// point in the debugger.
        /// </summary>
        public RuleEditorPackage()
        {
            Trace.WriteLine(String.Format(CultureInfo.CurrentCulture, "Entering constructor for class {0}.", this.GetType().Name));
        }

        /////////////////////////////////////////////////////////////////////////////
        // CBscPkgPackage Package Implementation
        #region Package Members

        /// <summary>
        /// Initialization routine for the package. This creates the editor factory instance
        /// </summary>
        protected override void Initialize()
        {
            Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
            
            base.Initialize();

            //Create Editor Factory
            editorFactory = new EditorFactory(this);

            base.RegisterEditorFactory(editorFactory);

            AdviseProjectItemEvents();
        }

        /// <summary>
        /// Dispose the package
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Dispose() of: {0}", this.ToString()));

            base.Dispose(disposing);
            UnAdviseProjectItemEvents();
        }

        #endregion

        #region ProjectItemEvents Members
        private EnvDTE.ProjectItemsEvents projectItemsEvents;

        private EnvDTE.ProjectItemsEvents ProjectItemsEvents
        {
            get
            {
                if (projectItemsEvents == null)
                {
                    EnvDTE.DTE dte = GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
                    projectItemsEvents = dte.Events.GetObject("ProjectItemsEvents") as EnvDTE.ProjectItemsEvents;
                }

                return projectItemsEvents;
            }
        }

        private void AdviseProjectItemEvents()
        {
            ProjectItemsEvents.ItemAdded += new EnvDTE._dispProjectItemsEvents_ItemAddedEventHandler(ProjectItemsEvents_ItemAdded);
            ProjectItemsEvents.ItemRemoved += new EnvDTE._dispProjectItemsEvents_ItemRemovedEventHandler(ProjectItemsEvents_ItemRemoved);
            ProjectItemsEvents.ItemRenamed += new EnvDTE._dispProjectItemsEvents_ItemRenamedEventHandler(ProjectItemsEvents_ItemRenamed);
        }

        private void UnAdviseProjectItemEvents()
        {
            ProjectItemsEvents.ItemAdded -= ProjectItemsEvents_ItemAdded;
            ProjectItemsEvents.ItemRemoved -= ProjectItemsEvents_ItemRemoved;
            ProjectItemsEvents.ItemRenamed -= ProjectItemsEvents_ItemRenamed;
        }

        private void ProjectItemsEvents_ItemRenamed(EnvDTE.ProjectItem item, string oldName)
        {
            //TODO: Provide Implementation
        }

        private void ProjectItemsEvents_ItemRemoved(EnvDTE.ProjectItem item)
        {
            //TODO: Provide Implementation
        }

        private void ProjectItemsEvents_ItemAdded(EnvDTE.ProjectItem item)
        {
            //TODO: Provide Implementation
        }
        #endregion
    }
}
